#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
#include <pthread.h>

#define PORT 8080

// 线程处理客户端请求的函数
void* handle_client(void* arg) {
    int new_socket = *(int*)arg;
    char buffer[1024] = {0};

    // 接收客户端数据（阻塞调用）
    int valread = read(new_socket, buffer, 1024);
    if (valread < 0) {
        perror("read failed");
        close(new_socket);
        return nullptr;
    }
    std::cout << "Received from client: " << buffer << std::endl;

    // 回复客户端数据
    const char *response = "Hello from server!";
    send(new_socket, response, strlen(response), 0);
    std::cout << "Response sent to client." << std::endl;

    // 关闭客户端连接
    close(new_socket);
    return nullptr;
}

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);

    // 创建TCP套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 绑定套接字到端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 开始监听连接请求
    if (listen(server_fd, 3) < 0) {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    std::cout << "TCP Server waiting for client connections..." << std::endl;

    while (true) {
        // 接受客户端连接（阻塞调用）
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
            perror("accept failed");
            continue;
        }

        std::cout << "Connected to client!" << std::endl;

        // 创建线程来处理客户端请求
        pthread_t thread_id;
        if (pthread_create(&thread_id, nullptr, handle_client, (void*)&new_socket) != 0) {
            perror("pthread_create failed");
            close(new_socket);
        } else {
            // 分离线程，避免阻塞
            pthread_detach(thread_id);
        }
    }

    return 0;
}
